package cn.cuilan.hutool.core;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.convert.Converter;
import cn.hutool.core.convert.ConverterRegistry;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.CharsetUtil;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 类型转换
 *
 * @author zhangyan
 * @since 2023/1/4
 */
public class ConvertTest {

    /**
     * 转换为字符串
     */
    private static void toStr() {
        int a = 1;
        System.out.println("int -> String: " + Convert.toStr(a));

        long[] b = {1, 2, 3, 4, 5};
        System.out.println("long array -> String: " + Convert.toStr(b));
    }

    /**
     * 转换为指定类型数组
     */
    private static void toArray() {
        String[] strArr = {"1", "2", "3"};
        Integer[] intArr = Convert.toIntArray(strArr);
        System.out.println("String array -> int array:" + Arrays.toString(intArr));

        long[] longArr = {1, 2, 3, 4};
        Integer[] intArr2 = Convert.toIntArray(longArr);
        System.out.println("long array -> int array:" + Arrays.toString(intArr2));
    }

    /**
     * 转换为日期对象
     */
    private static void toDate() {
        String dateStr = "2023-01-04";
        Date date = Convert.toDate(dateStr);
        System.out.println("String date -> java.util.Date: " + date);
    }

    /**
     * 转换为集合
     */
    private static void toList() {
        Object[] a = {"a", "你", "好", "", 1};
        List<?> list = Convert.convert(List.class, a);
        System.out.println("Object array -> List: " + list);
        // 从4.1.11开始可以这么用
        List<?> newList = Convert.toList(a);
        System.out.println("Object array -> List: " + newList);
    }

    /**
     * 其它类型转换
     */
    private static void toTypeReference() {
        Object[] a = {"a", "你", "好", "", 1};
        List<String> list = Convert.convert(new TypeReference<List<String>>() {
        }, a);
        System.out.println("Object array -> List<String>: " + list);
    }

    /**
     * 半角和全角转换
     */
    private static void toSBCAndDBC() {
        String a = "123456789,.:";
        System.out.println("半角 -> 全角: " + Convert.toSBC(a));

        String b = "１２３４５６７８９，．：";
        System.out.println("全角 -> 半角: " + Convert.toDBC(b));
    }

    /**
     * 16进制（Hex）
     */
    private static void toHex() {
        String a = "我是一个小小的可爱的字符串";
        System.out.println(Convert.toHex(a, CharsetUtil.CHARSET_UTF_8));

        String hex = "e68891e698afe4b880e4b8aae5b08fe5b08fe79a84e58fafe788b1e79a84e5ad97e7aca6e4b8b2";
        System.out.println(Convert.hexToStr(hex, CharsetUtil.CHARSET_UTF_8));
    }

    /**
     * Unicode和字符串转换
     */
    private static void toUnicode() {
        String a = "我是一个小小的可爱的字符串";
        // 结果为："\\u6211\\u662f\\u4e00\\u4e2a\\u5c0f\\u5c0f\\u7684\\u53ef\\u7231\\u7684\\u5b57\\u7b26\\u4e32"
        String unicode = Convert.strToUnicode(a);
        System.out.println(unicode);

        String raw = Convert.unicodeToStr(unicode);
        System.out.println(raw);
    }

    /**
     * 编码转换
     */
    private static void toCharset() {
        String utf_8 = "我不是乱码";
        System.out.println("UTF-8: " + utf_8);
        String iso_8859_1 = Convert.convertCharset(utf_8, CharsetUtil.UTF_8, CharsetUtil.ISO_8859_1);
        System.out.println("UTF-8 -> ISO-8859-1: " + iso_8859_1);

        String raw = Convert.convertCharset(iso_8859_1, CharsetUtil.ISO_8859_1, CharsetUtil.UTF_8);
        System.out.println("ISO-8859-1 -> UTF-8: " + raw);

        String gbk = Convert.convertCharset(utf_8, CharsetUtil.UTF_8, CharsetUtil.GBK);
        System.out.println("UTF-8 -> GKB: " + gbk);

        // UTF-8编码后用GBK解码再用GBK编码后用UTF-8解码会存在某些中文转换失败的问题
        String result = Convert.convertCharset(gbk, CharsetUtil.GBK, CharsetUtil.UTF_8);
        System.out.println("GKB -> UTF-8: " + result);
    }

    /**
     * 时间单位转换
     */
    private static void toTimeUnit() {
        long nanoseconds = 60000000000L;
        System.out.println("nanoseconds: " + nanoseconds);

        long microseconds = Convert.convertTime(nanoseconds, TimeUnit.NANOSECONDS, TimeUnit.MICROSECONDS);
        System.out.println("microseconds: " + microseconds);

        long milliseconds = Convert.convertTime(microseconds, TimeUnit.MICROSECONDS, TimeUnit.MILLISECONDS);
        System.out.println("milliseconds: " + milliseconds);

        long seconds = Convert.convertTime(milliseconds, TimeUnit.MILLISECONDS, TimeUnit.SECONDS);
        System.out.println("seconds: " + seconds);

        long minutes = Convert.convertTime(seconds, TimeUnit.SECONDS, TimeUnit.MINUTES);
        System.out.println("minutes: " + minutes);
    }

    /**
     * 金额大小写转换
     */
    private static void toChineseAmount() {
        double a = 67556.32;
        String digitUppercase = Convert.digitToChinese(a);
        System.out.println(digitUppercase);
    }

    /**
     * 数字转换
     */
    private static void toNumName() {
        // 数字转为英文表达 ONE HUNDRED AND CENTS TWENTY THREE ONLY
        String format = Convert.numberToWord(100.23);
        System.out.println(format);

        // 数字简化 1.2k
        String format1 = Convert.numberToSimple(1200);
        System.out.println(format1);

        // 数字转中文 一万零八百八十九点七二
        String f1 = Convert.numberToChinese(10889.72356, false);
        System.out.println(f1);

        // 使用金额大写 壹万贰仟陆佰伍拾叁
        String f2 = Convert.numberToChinese(12653, true);
        System.out.println(f2);

        // 数字中文表示转换为数字 1012
        int f3 = Convert.chineseToNumber("一千零一十二");
        System.out.println(f3);
    }

    /**
     * 原始类和包装类转换
     */
    private static void toWarp() {
        // 去包装
        Class<?> wrapClass = Integer.class;
        // 结果为：int.class
        Class<?> unWrap = Convert.unWrap(wrapClass);
        System.out.println(unWrap.getName());

        // 包装
        Class<?> primitiveClass = long.class;
        // 结果为：Long.class
        Class<?> wrap = Convert.wrap(primitiveClass);
        System.out.println(wrap.getName());
    }

    /**
     * 自定义类型转换-ConverterRegistry
     */
    private static void useConverterRegistry() {
        int a = 3423;
        ConverterRegistry converterRegistry = ConverterRegistry.getInstance();
        String result = converterRegistry.convert(String.class, a);
        System.out.println(result);
    }

    /**
     * 自定义转换器
     */
    private static void customConverter() {
        ConverterRegistry converterRegistry = ConverterRegistry.getInstance();
        converterRegistry.putCustom(User.class, CustomConverter.class);
        int age = 29;
        User user = converterRegistry.convert(User.class, age);
        System.out.println(user);
    }

    private static class CustomConverter implements Converter<User> {
        @Override
        public User convert(Object value, User user) throws IllegalArgumentException {
            return new User(value.toString());
        }
    }

    private static class User {
        public String age;

        public User(String age) {
            this.age = age;
        }

        @Override
        public String toString() {
            return "Custom User, age: " + age;
        }
    }

    public static void main(String[] args) {
        //toStr();
        //toArray();
        //toDate();
        //toList();
        //toTypeReference();
        //toSBCAndDBC();
        //toHex();
        //toUnicode();
        //toCharset();
        //toTimeUnit();
        //toChineseAmount();
        //toNumName();
        //toWarp();
        //useConverterRegistry();
        //customConverter();
    }

}
